/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.javanile.sms;

import java.io.IOException;

import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

import javax.wireless.messaging.*;


public class Server implements MessageListener, Runnable {

	 /** SMS message connection for inbound text messages. */
    MessageConnection smsconn;


	/** The port on which we send SMS messages */
    String smsPort;


    Incoming receiveAction;

		/** Current message read from the network. */
		Message msg;

		/** Flag to signal end of processing. */
		boolean done;

		/** Address of the message's sender */
		String senderAddress;

		/** instance of a thread for asynchronous networking and user interface. */
		Thread thread;

		/** Connections detected at start up. */
		String[] connections;

	    public SMSSender sender;

		public Server(MIDlet mid) {
			smsPort = mid.getAppProperty("SMS-Port");
			//smsPort = port;
	        sender = new SMSSender(smsPort);
		}

		//public Server() {
	        //this("50001");
		//}

		public void start() {
			/** SMS connection to be read. */
			String smsConnection = "sms://:" + smsPort;

			/** Open the message connection. */
			if (smsconn == null) {
				try {
					smsconn = (MessageConnection)Connector.open(smsConnection);
					smsconn.setMessageListener(this);
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}

			/** Initialize the text if we were started manually. */
			connections = PushRegistry.listConnections(true);

			if ((connections == null) || (connections.length == 0)) {
				//content.setString("Waiting for SMS on port " + smsPort + "...");
			}

			done = false;
			thread = new Thread(this);
			thread.start();

		}

		public void stop() {

		}

		public void send(String number, String message) {
			sender.send("sms://"+number,message);
		}

		public void receive(Server.Incoming inc) {
                    receiveAction = inc;
		}

		public void notifyIncomingMessage(MessageConnection conn) {
			//System.out.println("ni:in");
			//if (thread == null) {
				//System.out.println("ni:null");
				done = false;
				thread = new Thread(this);
				thread.start();
			//}
		}

		/** Message reading thread. */
		public void run() {
			/** Check for sms connection. */
			try {
				msg = smsconn.receive();

				if (msg != null) {
					senderAddress = msg.getAddress();
					//content.setTitle("From: " + senderAddress);

					if (msg instanceof TextMessage) {
						//content.setString(((TextMessage)msg).getPayloadText());
						String r = ((TextMessage)msg).getPayloadText();
						System.out.println("RECEIVED: "+r);
                                                receiveAction.received(r);
					} else {
						StringBuffer buf = new StringBuffer();
						byte[] data = ((BinaryMessage)msg).getPayloadData();

						for (int i = 0; i < data.length; i++) {
							int intData = (int)data[i] & 0xFF;

							if (intData < 0x10) {
								buf.append("0");
							}

							buf.append(Integer.toHexString(intData));
							buf.append(' ');
						}

						//content.setString(buf.toString());
					}

					//content.addCommand(replyCommand);
					//display.setCurrent(content);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		public class SMSSender implements CommandListener, Runnable {
			/** user interface command for indicating Send request */
			Command sendCommand = new Command("Send", Command.OK, 1);

			/** user interface command for going back to the previous screen */
			Command backCommand = new Command("Back", Command.BACK, 2);

			/** Display to use. */
			Display display;

			/** The port on which we send SMS messages */
			String smsPort;

			/** The URL to send the message to */
			String destinationAddress;
			String destinationMessage;

			/** Area where the user enters a message to send */
			TextBox messageBox;

			/** Where to return if the user hits "Back" */
			Displayable backScreen;

			/** Displayed when a message is being sent */
			Displayable sendingScreen;

			/**
			 * Initialize the MIDlet with the current display object and
			 * graphical components.
			 */
			public SMSSender(String smsPort) {
				this.smsPort = smsPort;
				this.destinationAddress = null;


			}

			/**
			 * Prompt for message and send it
			 */
			public void promptAndSend(String destinationAddress) {
				this.destinationAddress = destinationAddress;
				//display.setCurrent(messageBox);
			}

			/**
			 * Respond to commands, including exit
			 * @param c user interface command requested
			 * @param s screen object initiating the request
			 */
			public void commandAction(Command c, Displayable s) {
				try {
					if (c == backCommand) {
						display.setCurrent(backScreen);
					} else if (c == sendCommand) {
						display.setCurrent(sendingScreen);
						new Thread(this).start();
					}
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}

			public void send(String a, String m) {
				this.destinationAddress = a;
				this.destinationMessage = m;

				new Thread(this).start();
			}

			/**
			 * Send the message. Called on a separate thread so we don't have
			 * contention for the display
			 */
			public void run() {
				String address = destinationAddress + ":" + smsPort;

				MessageConnection smsconn = null;

				try {
					/** Open the message connection. */
					smsconn = (MessageConnection)Connector.open(address);

					TextMessage txtmessage =
						(TextMessage)smsconn.newMessage(MessageConnection.TEXT_MESSAGE);
					txtmessage.setAddress(address);
					//txtmessage.setPayloadText(messageBox.getString());
					txtmessage.setPayloadText(destinationMessage);
					smsconn.send(txtmessage);
				} catch (Throwable t) {
					System.out.println("Send caught: ");
					t.printStackTrace();
				}

				if (smsconn != null) {
					try {
						smsconn.close();
					} catch (IOException ioe) {
						System.out.println("Closing connection caught: ");
						ioe.printStackTrace();
					}
				}
			}
		}

                public interface Incoming {
    	public void received(String msg);

    }

	}
